/**
 * Collections 相关的 TanStack Query Hooks
 * 提供集合数据的查询、创建、更新、删除、重排序功能
 */
import {useQuery, useMutation, useQueryClient, type UseQueryOptions, type QueryKey} from '@tanstack/react-query';
import {QueryKeys} from '@/lib/queryClient';
import * as collectionsApi from '@/api/collections';
import {
    CreateCollectionRequest,
    UpdateCollectionRequest,
    AttachCollectionRequest,
    ReorderCollectionsRequest,
    CollectionWithTabsDto,
} from '@/api/types';
import {useToast} from '@/hooks/ui/useToast';

/**
 * 获取空间下的集合列表
 * @param spaceId - 空间 ID
 * @param options
 * @returns Query 对象，包含 data、isLoading、error 等状态
 */
export function useCollectionsBySpace<TData = CollectionWithTabsDto[]>(
    spaceId: number | null,
    options?: Omit<
        UseQueryOptions<CollectionWithTabsDto[], unknown, TData, QueryKey>,
        'queryKey' | 'queryFn'
    >
) {
    return useQuery<CollectionWithTabsDto[], unknown, TData>({
        queryKey: spaceId ? QueryKeys.collections(spaceId) : ['collections', 'null'],
        queryFn: () => {
            if (!spaceId) {
                throw new Error('空间 ID 不能为空');
            }
            return collectionsApi.getCollectionsBySpace(spaceId);
        },
        enabled: !!spaceId, // 仅当 spaceId 存在时才执行查询
        ...(options ?? {}),
    });
}

/**
 * 在空间下创建集合（带乐观更新）
 * @returns Mutation 对象
 */
export function useCreateCollection() {
    const queryClient = useQueryClient();
    const {success, error} = useToast();

    return useMutation({
        mutationFn: ({
            spaceId,
            data,
        }: {
            spaceId: number;
            data: CreateCollectionRequest;
        }) => collectionsApi.createCollection(spaceId, data),
        onMutate: async ({spaceId, data}) => {
            await queryClient.cancelQueries({queryKey: QueryKeys.collections(spaceId)});
            const previousCollections = queryClient.getQueryData<CollectionWithTabsDto[]>(
                QueryKeys.collections(spaceId)
            );

            // 乐观更新：立即添加临时数据（包含空的 items 数组）
            const optimisticCollection: CollectionWithTabsDto = {
                collection: {
                    id: Date.now(), // 临时 ID
                    name: data.name,
                    owner_id: 0,
                    created_at: new Date().toISOString(),
                    updated_at: new Date().toISOString(),
                },
                binding: {
                    space_id: spaceId,
                    collection_id: Date.now(),
                    position: data.position ?? 0,
                    owner_id: 0,
                    created_at: new Date().toISOString(),
                    updated_at: new Date().toISOString(),
                },
                items: [], // 新创建的集合没有标签页
            };

            queryClient.setQueryData<CollectionWithTabsDto[]>(
                QueryKeys.collections(spaceId),
                (old) => [...(old || []), optimisticCollection]
            );

            return {previousCollections, spaceId};
        },
        onSuccess: (_data, variables) => {
            queryClient.invalidateQueries({queryKey: QueryKeys.collections(variables.spaceId)});
            success('集合创建成功');
        },
        onError: (_err, _variables, context) => {
            if (context?.previousCollections) {
                queryClient.setQueryData(
                    QueryKeys.collections(context.spaceId),
                    context.previousCollections
                );
            }
            error('集合创建失败');
        },
    });
}

/**
 * 更新集合（带乐观更新）
 * @returns Mutation 对象
 */
export function useUpdateCollection() {
    const queryClient = useQueryClient();
    const {success, error} = useToast();

    return useMutation({
        mutationFn: ({
            collectionId,
            data,
        }: {
            collectionId: number;
            spaceId?: number;
            data: UpdateCollectionRequest;
        }) => collectionsApi.updateCollection(collectionId, data),
        onSuccess: (_data, variables) => {
            // 失效特定空间的集合列表缓存
            if (variables.spaceId) {
                queryClient.invalidateQueries({
                    queryKey: QueryKeys.collections(variables.spaceId),
                });
            } else {
                // 如果没有提供 spaceId，失效所有 collections 查询
                queryClient.invalidateQueries({
                    queryKey: ['spaces'],
                    predicate: (query) => query.queryKey[0] === 'spaces' && query.queryKey[2] === 'collections',
                });
            }
            success('集合更新成功');
        },
        onError: () => {
            error('集合更新失败');
        },
    });
}

/**
 * 删除集合
 * @returns Mutation 对象
 */
export function useDeleteCollection() {
    const queryClient = useQueryClient();
    const {success, error} = useToast();

    return useMutation({
        mutationFn: ({
            collectionId,
        }: {
            collectionId: number;
            spaceId?: number;
        }) => collectionsApi.deleteCollection(collectionId),
        onSuccess: (_data, variables) => {
            // 失效特定空间的集合列表缓存
            if (variables.spaceId) {
                queryClient.invalidateQueries({
                    queryKey: QueryKeys.collections(variables.spaceId),
                });
            } else {
                // 如果没有提供 spaceId，失效所有 collections 查询
                queryClient.invalidateQueries({
                    queryKey: ['spaces'],
                    predicate: (query) => query.queryKey[0] === 'spaces' && query.queryKey[2] === 'collections',
                });
            }
            success('集合删除成功');
        },
        onError: () => {
            error('集合删除失败');
        },
    });
}

/**
 * 关联集合到空间
 * @returns Mutation 对象
 */
export function useAttachCollectionToSpace() {
    const queryClient = useQueryClient();
    const {success, error} = useToast();

    return useMutation({
        mutationFn: ({
            spaceId,
            data,
        }: {
            spaceId: number;
            data: AttachCollectionRequest;
        }) => collectionsApi.attachCollectionToSpace(spaceId, data),
        onSuccess: (_data, variables) => {
            queryClient.invalidateQueries({queryKey: QueryKeys.collections(variables.spaceId)});
            success('集合关联成功');
        },
        onError: () => {
            error('集合关联失败');
        },
    });
}

/**
 * 重排序空间下的集合
 * 组件层已做同步乐观更新和失败回滚，Hook 只负责：
 * - onSuccess: 合并后端返回的最新数据（updated_at 等）
 * @returns Mutation 对象
 */
export function useReorderCollections() {
    const queryClient = useQueryClient();

    return useMutation({
        mutationFn: ({
            spaceId,
            data,
        }: {
            spaceId: number;
            data: ReorderCollectionsRequest;
        }) => collectionsApi.reorderCollections(spaceId, data),
        onSuccess: (updatedCollections, variables) => {
            // 合并后端返回的最新数据（含 updated_at 等服务端字段）
            if (updatedCollections && updatedCollections.length > 0) {
                queryClient.setQueryData<CollectionWithTabsDto[]>(
                    QueryKeys.collections(variables.spaceId),
                    (old) => {
                        if (!old) return old;

                        const updatedMap = new Map(
                            updatedCollections.map(item => [item.collection.id, item])
                        );

                        return old.map(collection => {
                            const updated = updatedMap.get(collection.collection.id);
                            if (updated) {
                                return {
                                    ...collection,
                                    collection: updated.collection,
                                    binding: updated.binding,
                                };
                            }
                            return collection;
                        }).sort((a, b) => a.binding.position - b.binding.position);
                    }
                );
            }
        },
    });
}
